﻿/******************************************************************************
	Cobalt - utility libraries for building XNA games
	Copyright (C) 2008 Philip Djonov

	This program is free software; you can redistribute it and/or modify it
	under the terms of the GNU General Public License as published by the Free
	Software Foundation; either version 2 of the License, or (at your option)
	any later version.

	This program is distributed in the hope that it will be useful, but
	WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
	or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
	for more details.

	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the
	
		Free Software Foundation, Inc.
		51 Franklin Street, Fifth Floor
		Boston, MA  02110-1301, USA.
******************************************************************************/

using System;
using System.Collections.Generic;
using System.IO;

namespace Cobalt.Content.Pipeline.Quake
{

	public class QuakeFs
	{
		private List<string> searchPaths = new List<string>();
		public List<string> SearchPaths
		{
			get { return searchPaths; }
		}

		public event DependencyEventHandler OpeningPath;
		protected virtual void OnOpeningPath( DependencyEventArgs e )
		{
			if( OpeningPath != null )
				OpeningPath( this, e );
		}

		protected void OnOpeningPath( string dependencyPath )
		{
			OnOpeningPath( new DependencyEventArgs( dependencyPath ) );
		}

		public Stream OpenPath( string quakePath, out string osPath )
		{
			foreach( string basePath in searchPaths )
			{
				string fullPath = Path.Combine( basePath, quakePath );
				if( File.Exists( fullPath ) )
				{
					OnOpeningPath( fullPath );

					osPath = fullPath.Replace( '/', Path.DirectorySeparatorChar );
					return File.OpenRead( fullPath );
				}
			}

			throw new FileNotFoundException( string.Format( "Unable to open QuakeFs file '{0}'.", quakePath ), quakePath );
		}

		public string GetOsPath( string quakePath )
		{
			foreach( string basePath in searchPaths )
			{
				string fullPath = Path.Combine( basePath, quakePath );
				if( File.Exists( fullPath ) )
					return fullPath.Replace( '/', Path.DirectorySeparatorChar );
			}

			return null;
		}

		public IEnumerable<string> GetFiles( string directory, string searchPattern )
		{
			directory = directory.Replace( Path.DirectorySeparatorChar, '/' );
			if( directory[directory.Length - 1] != '/' )
				directory += '/';

			Dictionary<string, bool> ret = new Dictionary<string, bool>();

			foreach( string basePath in searchPaths )
			{
				string searchDirectory = Path.Combine( basePath, directory );

				foreach( string path in Directory.GetFiles( searchDirectory, searchPattern, SearchOption.TopDirectoryOnly ) )
				{
					ret[directory + path.Substring( searchDirectory.Length )] = true;
				}
			}

			return ret.Keys;
		}
		
	}

	public class DependencyEventArgs : EventArgs
	{
		public string DependencyPath { get; private set; }
		public DependencyEventArgs( string dependencyPath )
		{
			this.DependencyPath = dependencyPath;
		}
	}

	public delegate void DependencyEventHandler( object sender, DependencyEventArgs e );

}